// import com.alibaba.druid.DbType;
// import com.alibaba.druid.sql.SQLUtils;
// import com.alibaba.druid.sql.ast.SQLExpr;
// import com.alibaba.druid.sql.ast.SQLName;
// import com.alibaba.druid.sql.ast.statement.SQLExplainStatement;
// import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

#include "MySqlExplainStatement.h"
#include "../../../../../DbType.h"
#include "../../../../SQLUtils.h"
#include "../../../../ast/SQLExpr.h"
#include "../../../../ast/SQLName.h"
#include "../../../../ast/statement/SQLExplainStatement.h"
#include "../../visitor/MySqlASTVisitor.h"
#include "../../../../visitor/SQLASTVisitor.h"
#include "../../../../../utils/instanceof.h"

MySqlExplainStatement::MySqlExplainStatement()
    : SQLExplainStatement(DbType_ptr(new DbType(&DbType::mysql)))
{
}

MySqlExplainStatement::MySqlExplainStatement(DbType_ptr dbType)
    : SQLExplainStatement(dbType)
{
}

// @Override
void MySqlExplainStatement::accept0(MySqlASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(MySqlExplainStatement)))
  {
    // tbl_name [col_name | wild]
    if (tableName != nullptr)
    {
      tableName->accept(visitor);

      if (columnName != nullptr)
      {
        columnName->accept(visitor);
      }
      else if (wild != nullptr)
      {
        wild->accept(visitor);
      }
    }
    else
    {
      // {explainable_stmt | FOR CONNECTION connection_id}
      if (connectionId != nullptr)
      {
        connectionId->accept(visitor);
      }
      else
      {
        if (statement != nullptr)
        {
          statement->accept(visitor);
        }
      }
    }
  }

  visitor->endVisit(SharedObject(MySqlExplainStatement));
}

void MySqlExplainStatement::accept0(SQLASTVisitor_ptr visitor)
{
  if (instanceof <SQLASTVisitor, MySqlASTVisitor>(visitor))
  {
    accept0(std::dynamic_pointer_cast<MySqlASTVisitor>(visitor));
  }
  else
  {
    SQLExplainStatement::accept0(visitor);
  }
}

string_ptr MySqlExplainStatement::toString()
{
  return SQLUtils::toMySqlString(SharedObject(MySqlExplainStatement));
}

BOOL_ptr MySqlExplainStatement::isDescribe()
{
  return describe;
}

void MySqlExplainStatement::setDescribe(BOOL_ptr describe)
{
  this->describe = describe;
}

SQLName_ptr MySqlExplainStatement::getTableName()
{
  return tableName;
}

void MySqlExplainStatement::setTableName(SQLName_ptr tableName)
{
  this->tableName = tableName;
}

SQLName_ptr MySqlExplainStatement::getColumnName()
{
  return columnName;
}

void MySqlExplainStatement::setColumnName(SQLName_ptr columnName)
{
  this->columnName = columnName;
}

SQLExpr_ptr MySqlExplainStatement::getWild()
{
  return wild;
}

void MySqlExplainStatement::setWild(SQLExpr_ptr wild)
{
  this->wild = wild;
}

SQLExpr_ptr MySqlExplainStatement::getConnectionId()
{
  return connectionId;
}

void MySqlExplainStatement::setConnectionId(SQLExpr_ptr connectionId)
{
  this->connectionId = connectionId;
}

BOOL_ptr MySqlExplainStatement::isDistributeInfo()
{
  return distributeInfo;
}

void MySqlExplainStatement::setDistributeInfo(BOOL_ptr distributeInfo)
{
  this->distributeInfo = distributeInfo;
}
